﻿using System.Collections.Generic;
using KaytechSoftware.Cms.Entities.Interfaces;
using KaytechSoftware.Cms.Services.Interfaces.Entity;

namespace KaytechSoftware.Cms.Services.Services.Entity
{
    public abstract class EntityBaseService<TEntity, TEntityDto> : IEntityService<TEntityDto> where TEntity : IEntity, new() where TEntityDto : class, IDto
    {
        protected readonly IUnitOfWorkService UnitOfWorkService;
        protected readonly IRepository<TEntity> EntityRepository;

        protected EntityBaseService(IUnitOfWorkService unitOfWorkService, IRepository<TEntity> entityRepository)
        {
            UnitOfWorkService = unitOfWorkService;
            EntityRepository = entityRepository;
        }

        public abstract void Save(TEntityDto dto);
        public abstract IList<TEntityDto> GetAll();

        protected TEntity GetInstance(long id)
        {
            return id > 0 ? EntityRepository.GetById(id) : new TEntity();
        }

        protected void Store(TEntity entity)
        {
            if (entity.Id > 0)
                EntityRepository.Edit(entity);
            else
                EntityRepository.Add(entity);
        }

        public virtual void Delete(long id)
        {
            using (var unitOfWork = UnitOfWorkService.Create())
            {
                var entity = EntityRepository.GetById(id);
                EntityRepository.Delete(entity);
                unitOfWork.Commit();
            }
        }

        public virtual TEntityDto GetDtoById(long id)
        {
            var entity = GetById(id);
            var constructorInfo = typeof(TEntityDto).GetConstructor(new[] { entity.GetType() });
            if (constructorInfo == null)
                return null;

            return constructorInfo.Invoke(new object[] { entity }) as TEntityDto;
        }

        protected TEntity GetById(long id)
        {
            using (UnitOfWorkService.Create())
            {
                var entity = EntityRepository.GetById(id);
                return entity;
            }
        }
    }
}
